package com.meeruu.sg.account.core.domain.biz;

import com.meeruu.common.model.enums.SysConfigCodeEnum;
import com.meeruu.sg.account.core.api.exception.AccountException;
import com.meeruu.sg.account.core.api.exception.ErrorCode;
import com.meeruu.sg.account.core.domain.biz.cache.LocalCacheBiz;
import com.meeruu.sg.account.core.domain.mapper.SysCoreConfigMapper;
import com.meeruu.sg.account.core.domain.model.SysCoreConfig;
import com.meeruu.sg.account.core.domain.model.enums.StatusEnums;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author: fei.y
 * @Description:
 * @Date: Created in 2019/6/28
 */
@Service
public class SysCoreConfigBiz {

    @Resource
    private SysCoreConfigMapper sysCoreConfigMapper;

    @Autowired
    private LocalCacheBiz localCacheService;

    public List<SysCoreConfig> queryAll() {
        return sysCoreConfigMapper.selectAll();
    }

    public SysCoreConfig queryByCode(String code) {
        if (StringUtils.isBlank(code)) {
            return null;
        }
        List<SysCoreConfig> configs = localCacheService.getSysCoreConfig();
        if (CollectionUtils.isEmpty(configs)) {
            return null;
        }

        Optional<SysCoreConfig> config = configs.stream()
                .filter(x -> StringUtils.equalsIgnoreCase(x.getCode(), code) && StatusEnums.ENABLE.getCode().equals(x.getStatus()))
                .findFirst();

        return config.orElse(null);
    }

    public SysCoreConfig queryByTime(String code, Date time) {
        if (StringUtils.isBlank(code)) {
            return null;
        }
        List<SysCoreConfig> configs = localCacheService.getSysCoreConfig();
        if (CollectionUtils.isEmpty(configs)) {
            return null;
        }
        configs = configs.stream()
                .filter(x -> StringUtils.equalsIgnoreCase(x.getCode(), code))
                .collect(Collectors.toList());
        if (time == null) {
            time = new Date();
        }

        final Date filterTime = time;
        //查询在给定时间之后的,距离时间最近的一条信息
        Optional<SysCoreConfig> config = configs.stream()
                .filter(x -> x.getCreateTime().before(filterTime)).max(Comparator.comparing(SysCoreConfig::getCreateTime));

        return config.orElse(null);
    }

//    @Override
//    public void modifyConfig(SysCoreConfig SysCoreConfig) {
//        SysCoreConfigMapper.updateByPrimaryKey(SysCoreConfig);
//    }

    public void removeConfig(Integer id) {
        if (id == null) {
            throw new AccountException(ErrorCode.PARAM_ERROR);
        }
        sysCoreConfigMapper.updateStatus(id, StatusEnums.DISABLE.getCode());
    }


    public void addConfigList(List<SysCoreConfig> configs) {
        if (CollectionUtils.isEmpty(configs) ) {
            throw new AccountException(ErrorCode.PARAM_ERROR);
        }

        List<String> codes = configs.stream().map(SysCoreConfig::getCode).distinct().collect(Collectors.toList());

        //将历史数据状态置为无效
        sysCoreConfigMapper.updateStatusList(codes);

        configs.forEach(x -> {
            SysConfigCodeEnum codeEnum = SysConfigCodeEnum.getByCode(x.getCode());
            if (codeEnum == null) {
                throw new AccountException(ErrorCode.PARAM_ERROR.getCode(), "无效的系统参数," + x.getCode());
            }
            x.setName(codeEnum.getName());
            x.setValueType(codeEnum.getValueType());
            x.setDescription(codeEnum.getDesc());
            x.setStatus(StatusEnums.ENABLE.getCode());
        });

        if (sysCoreConfigMapper.addConfigList(configs) <= 0) {
            throw new AccountException(ErrorCode.MODIFY_FAILURE);
        }
    }

    public void saveWithdrawConfigList(List<SysCoreConfig> configs) {
        if (CollectionUtils.isEmpty(configs) ) {
            throw new AccountException(ErrorCode.PARAM_ERROR);
        }

        List<String> codes = configs.stream().map(SysCoreConfig::getCode).distinct().collect(Collectors.toList());

        //将历史数据状态置为无效
        sysCoreConfigMapper.updateStatusList(codes);

        configs.forEach(x -> {
            SysConfigCodeEnum codeEnum = SysConfigCodeEnum.getByCode(x.getCode());
            if (codeEnum == null) {
                throw new AccountException(ErrorCode.PARAM_ERROR.getCode(), "无效的系统参数," + x.getCode());
            }
            x.setName(codeEnum.getName());
            x.setValueType(codeEnum.getValueType());
            x.setDescription(codeEnum.getDesc());
        });

        if (sysCoreConfigMapper.addConfigList(configs) <= 0) {
            throw new AccountException(ErrorCode.MODIFY_FAILURE);
        }
    }

    public List<SysCoreConfig> queryConfigList(List<String> codes) {
        if (CollectionUtils.isEmpty(codes)) {
            return new ArrayList<>();
        }
        return codes.stream().map(this::queryByCode).collect(Collectors.toList());
    }

    public List<SysCoreConfig> queryConfigs(List<String> codes, Date time) {
        if (CollectionUtils.isEmpty(codes)) {
            return new ArrayList<>();
        }
        return codes.stream().map(x -> this.queryByTime(x, time)).collect(Collectors.toList());
    }

    public List<SysCoreConfig> queryWithdrawConfig(List<String> codes) {
        if (CollectionUtils.isEmpty(codes)) {
            return new ArrayList<>();
        }
        List<SysCoreConfig> sysConfigs = sysCoreConfigMapper.queryByCodes(codes);
        return codes.stream().map(x -> this.getConfig(sysConfigs, x)).collect(Collectors.toList());
    }

    private SysCoreConfig getConfig(List<SysCoreConfig> configs, String code) {
        if (CollectionUtils.isEmpty(configs)) {
            return null;
        }
        configs = configs.stream()
                .filter(x -> StringUtils.equalsIgnoreCase(x.getCode(), code))
                .collect(Collectors.toList());

        Optional<SysCoreConfig> config = configs.stream()
                .sorted(Comparator.comparing(SysCoreConfig::getCreateTime).reversed())
                .findFirst();
        return config.isPresent() ? config.get() : null;
    }


}
